import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipInputStream;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class RABID extends JFrame {

  static final Color BACK_COLOR = new Color(213, 216, 225);
  static final int MIN_FRAME_HEIGHT = 600;
  static final int MIN_FRAME_WIDTH = 800;
  private static RABID singletonFrame;

  public static RABID getMainFrame() {
    return singletonFrame;
  }

  /**
   * Launch the application
   * 
   * @param args
   */
  public static void main(String args[]) {
    try {
      RABID frame = new RABID();
      frame.setVisible(true);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  private static Corpus createCorpusFromIndex() {
    InputStream input = null;
    try {
      input = FileStreamCreator.createInputStream("DTI.out");
      ZipInputStream zipIn = new ZipInputStream(input);
      DataInputStream dataInput = new DataInputStream(zipIn);
      zipIn.getNextEntry();
      return Corpus.createCorpus(dataInput, new File("DTI.out").length());
    } catch (FileNotFoundException e) {
      Util.errExit("Index file 'DTI.out' does not exist");
    } catch (IOException e) {
      Util.errExit("Index file 'DTI.out' could not be read from");
    } finally {
      Util.close(input);
    }
    return null;
  }

  /**
   * Create the frame
   */
  public RABID() {
    super();
    singletonFrame = this;
    corpus = createCorpusFromIndex();

    addComponentListener(new ComponentAdapter() {
      public void componentResized(ComponentEvent arg0) {
        setSize(new Dimension(Math.max(MIN_FRAME_WIDTH, getWidth()), Math.max(
            MIN_FRAME_HEIGHT, getHeight())));
      }
    });
    setTitle("PR1ME RABID beta 1.0");
    controlPanel = new ControlPanel(this);
    controlPanel2 = new ControlPanel2();
    browseTreePanel = new TreePanel(TreePanel.BROWSE_TREE);
    searchTreePanel = new TreePanel(TreePanel.SEARCH_TREE);
    contentPanel = new ContentPanel(this);
    contentPanel.setStatsContent(corpus.getStatsText());
    contentPanel.setIndexContent(corpus.getIndexText());

    browseTreePanel.getTreeStructure().initializeBrowseTree(corpus);

    getContentPane().setLayout(new BorderLayout());
    setBounds(100, 100, 500, 375);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    final JPanel topContainer = new JPanel();
    topContainer.setBackground(BACK_COLOR);
    topContainer.setLayout(new GridBagLayout());
    getContentPane().add(topContainer, BorderLayout.NORTH);

    // final JPanel controlPanel = new JPanel();
    final GridBagConstraints gridBagConstraints = new GridBagConstraints();
    gridBagConstraints.weighty = 1;
    gridBagConstraints.weightx = 1;
    topContainer.add(controlPanel, gridBagConstraints);

    final JPanel bottomContainer = new JPanel();
    bottomContainer.setBackground(BACK_COLOR);
    bottomContainer.setLayout(new GridBagLayout());
    getContentPane().add(bottomContainer, BorderLayout.SOUTH);
    bottomContainer.add(controlPanel2);

    final JPanel centerContainer = new JPanel();
    centerContainer.setLayout(new GridBagLayout());
    getContentPane().add(centerContainer, BorderLayout.CENTER);

    // final JPanel contentPanel = new JPanel();
    final GridBagConstraints gridBagConstraints_2 = new GridBagConstraints();
    gridBagConstraints_2.fill = GridBagConstraints.BOTH;
    gridBagConstraints_2.weighty = 1;
    gridBagConstraints_2.weightx = 1;
    gridBagConstraints_2.gridy = 0;
    gridBagConstraints_2.gridx = 0;
    centerContainer.add(contentPanel, gridBagConstraints_2);
    //
  }

  public TreePanel getBrowseTreePanel() {
    return browseTreePanel;
  }

  public ContentPanel getContentPanel() {
    return contentPanel;
  }

  public ControlPanel getControlPanel() {
    return controlPanel;
  }

  public Corpus getCorpus() {
    return corpus;
  }

  public TreePanel getSearchTreePanel() {
    return searchTreePanel;
  }

  public void updateButtons() {
    boolean enableDisplay = false;
    boolean enableSimilar = false;
    if (contentPanel == null) {
      // may not be initialized yet
      return;
    }
    String active = contentPanel.getActiveTabPanelString();
    if ("Results".equals(active)) {
      TreeObject node = searchTreePanel.getTreeStructure().getSelectedNode();
      if (node instanceof CorpusTreeObject) {
        CorpusTreeObject corpusTreeObject = (CorpusTreeObject) node;
        CorpusFile file = corpusTreeObject.getCorpusFile();
        curCorpusFile = file;
        enableDisplay = enableSimilar = true;
      }
    } else if ("Browse".equals(active)) {
      TreeObject node = browseTreePanel.getTreeStructure().getSelectedNode();
      if (node instanceof CorpusTreeObject) {
        CorpusTreeObject corpusTreeObject = (CorpusTreeObject) node;
        CorpusFile file = corpusTreeObject.getCorpusFile();
        curCorpusFile = file;
        enableDisplay = enableSimilar = true;
      }
    } else if ("Display".equals(active)) {
      curCorpusFile = contentPanel.getCorpusFile();
      enableSimilar = (curCorpusFile != null);
    }
    controlPanel2.enableDisplay(enableDisplay);
    controlPanel2.enableSimilar(enableSimilar);
  }

  private TreePanel browseTreePanel;
  private ContentPanel contentPanel;
  private ControlPanel controlPanel;
  private ControlPanel2 controlPanel2;
  private Corpus corpus;
  private CorpusFile curCorpusFile;
  private TreePanel searchTreePanel;

  public void doDisplay() {
    if (curCorpusFile == null) {
      return;
    }
    contentPanel.setCorpusFile(curCorpusFile);
    contentPanel.selectTab("Display");
  }

  public void doSimilarTo() {
    if (curCorpusFile == null) {
      return;
    }
    CorpusFile[] results = corpus.similarTo(curCorpusFile);
    TreeStructure tree = searchTreePanel.getTreeStructure();
    tree.setQueryResults(results);
    contentPanel.selectTab("Results");
  }

  public void doQuery(String userInput) {
    String[] args = userInput.split(" ");
    CorpusFile[] results = corpus.query(args);
    TreeStructure tree = searchTreePanel.getTreeStructure();
    tree.setQueryResults(results);
    contentPanel.selectTab("Results");
  }

}
